<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        background-color: #222;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div id="i-container">
      <canvas id="i-frostpad-canvas"></canvas>
    </div>


    <script src="src/WAAX.js"></script>
    <script src="src/Fader.js"></script>
    <script src="src/Noise.js"></script>
    <script src="src/FilterBank.js"></script>
    <script src="src/ADSR.js"></script>
    <script src="src/Chorus.js"></script>
    <script src="src/Spectrum.js"></script>
    <script src="src/StereoVisualizer.js"></script>

    <script>

      (function () {

        var cvs = document.getElementById('i-frostpad-canvas');
        var ctx = cvs.getContext('2d');

        // init
        var width = window.innerWidth;
        var height = window.innerHeight;
        cvs.width = width;
        cvs.height = height;

        var gridX = width / 5.0;
        var gridY = height / 3.0;
        var scaleFactor = 0.98;
        var angleFactor = 0.95;

        ctx.lineWidth = 0.15;
        // ctx.strokeStyle = '#3F3';

        function drawBox(cx, cy) {
          ctx.save();
          ctx.translate(cx, cy);
          ctx.scale(scaleFactor, scaleFactor);
          // ctx.rotate(angleFactor, angleFactor);
          ctx.beginPath();
          ctx.rect(-gridX*0.5, -gridY*0.5, gridX, gridY);
          ctx.strokeStyle = "#CCC";
          ctx.stroke();
          ctx.restore();
        }

        // drawBox(gridX * 0.5, gridY * 0.5, 0.5);

        function drawGrid() {
          for (var i = 0; i < 5; i++) {
            for (var j = 0; j < 3; j++) {
              drawBox(gridX * 0.5 + gridX * i, gridY * 0.5 + gridY * j);
            }
          }
        }

        drawGrid();


        var n = WX.Noise();
        var fb = WX.FilterBank();
        var env = WX.ADSR();
        var cho = WX.Chorus();
        var spec = WX.Spectrum();
        var viz = WX.StereoVisualizer();

        env.setADSR(0.25, 0.05, 0.75, 1.5);
        env.setParam('pMode', 'monophonic');

        WX.patch = n >> fb >> env >> cho >> WX.Dac;
        // WX.patch = cho >> spec;
        WX.patch = cho >> viz;

        // spec.setContext2D(ctx);


        var cp = {};
        var pitches = [31, 35, 36, 40, 41]; // g, b, c, e, f

        function getMousePosition(event) {
          var box = cvs.getBoundingClientRect();
          return {
            x: (event.clientX - box.left) / width,
            y: (event.clientY - box.top) / height
          };
        }

        function dragged(event) {
          var p = getMousePosition(event);
          fb.setParam('pPitch', pitches[Math.ceil(p.x * 5)-1]);
          cp = p;
          var chord;
          if (p.y < 0.33) {
            chord = 'mixolydian'
          } else if (p.y < 0.66) {
            chord = 'ionian';
          } else if (p.y < 1.0) {
            chord = 'lydian';
          }
          fb.setParam('pChord', chord);
          fb.setParam('pSlope', p.x, 1, WX.now+0.1);
          fb.setParam('pWidth', p.y, 1, WX.now+0.1);
        }

        function released(event) {
          env.noteOff();
          window.removeEventListener('mousemove', dragged, false);
          window.removeEventListener('mouseup', released, false);
        }

        var angle = 0.0;

        cvs.addEventListener('mousedown', function (event) {
          var p = getMousePosition(event);
          cp = p;
          fb.setParam('pPitch', pitches[Math.ceil(p.x * 5)-1]);
          var chord;
          if (p.y < 0.33) {
            chord = 'mixolydian'
          } else if (p.y < 0.66) {
            chord = 'ionian';
          } else if (p.y < 1.0) {
            chord = 'lydian';
          }
          fb.setParam('pChord', chord);
          angle = Math.random() * Math.PI * 2.0;
          fb.setParam('pSlope', p.x, 1, WX.now+0.1);
          fb.setParam('pWidth', p.y, 1, WX.now+0.1);

          env.noteOn();

          window.addEventListener('mousemove', dragged, false);
          window.addEventListener('mouseup', released, false);
        }, false);

        var unitX = width / 1024;
        var scale = height / 10;


        // spec.onDraw(function (buffer) {
        //   angle += 0.01;
        //   ctx.clearRect(0, 0, width, height);
        //   ctx.save();
        //   ctx.translate(width/2.0, height/2.0);
        //   ctx.scale(scale * 4, scale * 3);
        //   ctx.rotate(angle, 0.0);
        //   ctx.beginPath();
        //   for (var i = 0; i < bSize; i++) {
        //     // ctx.moveTo(i * unitX, scaleY);
        //     // var x = polarX[i] * 120;
        //     // var y = (buffer[i] * -0.01) * polarY[i] * 120;
        //     // ctx.lineTo(x, y);
        //     var x = polarX[i] * Math.log(i / 1, 2.0) / logmax;
        //     var y = polarY[i] * ((60 + buffer[i]) / 60.0) * frameWindow[i];
        //     ctx.lineTo(x, y);
        //   }
        //   ctx.stroke();
        //   ctx.restore();
        // });



        viz.onDraw(function (buffer1, buffer2) {
          // ctx.clearRect(0, 0, width, height);
          ctx.fillStyle = "rgba(16, 32, 16, 0.25)";
          ctx.fillRect(0, 0, width, height);
          // if (drawSwitch) {
            ctx.save();
            // ctx.translate(width/2, height/2);
            var gx = width / 32;
            var gy = height / 32;
            var cx = (cp.x * width) - ((cp.x * width) % gx);
            var cy = (cp.y * height) - ((cp.y * height) % gy);
            ctx.translate(cx, cy);


            // ctx.rotate(angle, 0.0);

            ctx.beginPath();



            // ctx.moveTo(0, (1.0 - buffer1[0] / 255) * 500);
            for (var i = 0; i < buffer1.length - 1; i++) {

                // var x1 = (i / 128 - 1.0) * width;
                // var y1 = (i / 128 - 1.0) * height;
                // var x2 = ((i+1) / 128 - 1.0) * width;
                // var y2 = ((i+1) / 128 - 1.0) * height;

                var x1 = (buffer1[i] / 128 - 1.0) * width * 4.0;
                var y1 = (buffer2[i] / 128 - 1.0) * height * 4.0;
                var x2 = (buffer1[i+1] / 128 - 1.0) * width * 4.0;
                var y2 = (buffer2[i+1] / 128 - 1.0) * height * 4.0;
                // // ctx.lineTo(x, y);

                // ctx.quadraticCurveTo(x1, y2, x2, y2);


                if (Math.random() > 0.5) {
                  ctx.moveTo(x1, y1);
                  ctx.quadraticCurveTo(x1, y2, x2, y2);
                } else {
                  ctx.moveTo(-x1, y1);
                  ctx.quadraticCurveTo(-x1, y2, -x2, y2);
                }

            }
            ctx.strokeStyle = "rgba(0, 255, 0, 0.8)";
            ctx.stroke();
            // ctx.beginPath();
            // ctx.moveTo(0, (1.0 - buffer2[0] / 255) * scale);
            // for (var i = 0; i < buffer2.length; i++) {
            //   ctx.lineTo(i * unitX, (1.0 - buffer2[i] / 255) * scale);
            // }
            // ctx.stroke();
            ctx.restore();
          // }
          // drawGrid();
        });

        function loop() {
          // spec.drawExt();
          viz.drawWaveform();
          requestAnimationFrame(loop);
        }
        loop();

      })();

    </script>
  </body>
</html>